package com.ruoyi.utils;

import cn.hutool.core.util.StrUtil;
import com.fhs.common.utils.StringUtil;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import org.apache.commons.collections4.map.LinkedMap;
import org.geotools.geometry.jts.JTS;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.geometry.jts.WKTReader2;
import org.geotools.referencing.CRS;
import org.locationtech.jts.geom.*;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKTReader;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CRSAuthorityFactory;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 坐标工具
 *
 * @liuliya
 */
public class CoordinateUtil {
    // WGS84标准参考椭球中的地球长半径(单位:米)
    private static final double EARTH_RADIUS_WGS84 = 6378137.0;

    //十进制经度
    public static final String LNG_PATTERN = "^[\\-\\+]?(0(\\.\\d{1,14})?|([1-9](\\d)?)(\\.\\d{1,14})?|1[0-7]\\d{1}(\\.\\d{1,14})?|180(\\.0{1,14})?)$";
    //纬度
    public static final String LAT_PATTERN = "^[\\-\\+]?((0|([1-8]\\d?))(\\.\\d{1,14})?|90(\\.0{1,14})?)$";
    /*
     * 度分秒正则
     * 每节的数字不能以 0 开头（比如不能写 08度，而要写 8 度）；
     * 秒的数字可以是小数，小数点后最多有两位数字；
     * 分隔三个节的标志符可以是空格、中横线、逗号、分号、°′"或者度分秒；
     * 取值范围，经度为 0度0分0秒 至 180度0分0秒；纬度为 0度0分0秒 至 90度0分0秒。
     * */
    //经度
    public static final String LNG_PATTERN_D = "^((\\d|[1-9]\\d|1[0-7]\\d)[°](\\d|[0-5]\\d)[′](\\d|[0-5]\\d)(\\.\\d{1,6})?[\\″]$)|(180[°]0[′]0[\\″]$)";
    //纬度
    public static final String LAT_PATTERN_D = "^((\\d|[1-8]\\d)[°](\\d|[0-5]\\d)[′](\\d|[0-5]\\d)(\\.\\d{1,6})?[\\″]$)|(90[°]0[′]0[\\″]$)";
    /**
     * 计算两个坐标的距离(粗略计算，单位:米)
     * 计算公式参照 google map 的距离计算
     *
     * @param lat1 坐标1纬度
     * @param lng1 坐标1经度
     * @param lat2 坐标2纬度
     * @param lng2 坐标2经度
     * @return
     */
    public static double distance(double lat1, double lng1, double lat2, double lng2) {
        double radLat1 = Math.toRadians(lat1);
        double radLat2 = Math.toRadians(lat2);

        double a = radLat1 - radLat2;
        double b = Math.toRadians(lng1) - Math.toRadians(lng2);

        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
                Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
        return Math.round(s * EARTH_RADIUS_WGS84);
    }

    /**
     * 度分秒转十进制度
     *
     * @param jwd
     * @return
     */
    public static String Dms2D(String jwd) {
        if (StrUtil.isNotEmpty(jwd) && (jwd.contains("°"))) {//如果不为空并且存在度单位
            //计算前进行数据处理
            jwd = jwd.replace("E", "").replace("N", "").replace(":", "").replace("：", "");
            double d = 0, m = 0, s = 0;
            d = Double.parseDouble(jwd.split("°")[0]);
            //不同单位的分，可扩展
            if (jwd.contains("′")) {//正常的′
                m = Double.parseDouble(jwd.split("°")[1].split("′")[0]);
            } else if (jwd.contains("'")) {//特殊的'
                m = Double.parseDouble(jwd.split("°")[1].split("'")[0]);
            }
            //不同单位的秒，可扩展
            if (jwd.contains("″")) {//正常的″
                //有时候没有分 如：112°10.25″
                s = jwd.contains("′") ? Double.parseDouble(jwd.split("′")[1].split("″")[0]) : Double.parseDouble(jwd.split("°")[1].split("″")[0]);
            } else if (jwd.contains("''")) {//特殊的''
                //有时候没有分 如：112°10.25''
                s = jwd.contains("'") ? Double.parseDouble(jwd.split("'")[1].split("''")[0]) : Double.parseDouble(jwd.split("°")[1].split("''")[0]);
            }
            jwd = String.valueOf(d + m / 60 + s / 60 / 60);//计算并转换为string
        }
        return jwd;
    }

    /**
     * @param sourceGeometry
     * @param targetSrid
     * @author 窦凯欣
     */
    public static Geometry coordinateTransform(Geometry sourceGeometry,int targetSrid){
        if (sourceGeometry == null || sourceGeometry.getSRID() == 0 || targetSrid == 0){
            return null;
        }
        try {
            CRSAuthorityFactory factory = CRS.getAuthorityFactory(true);
            CoordinateReferenceSystem source = factory.createCoordinateReferenceSystem("EPSG:" + sourceGeometry.getSRID());
            CoordinateReferenceSystem target = factory.createCoordinateReferenceSystem("EPSG:" + targetSrid);
            MathTransform transform = CRS.findMathTransform(source, target,true);
            Geometry res = JTS.transform(sourceGeometry, transform);
            if (res != null){
                res.setSRID(targetSrid);
            }
            return res;
        }catch (FactoryException | TransformException e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @param wkt
     * @param srid
     * @author 窦凯欣
     */
    public static Geometry createGeometry(String wkt,int srid){
        if (StringUtil.isEmpty(wkt)){
            return null;
        }
        try {
            WKTReader reader = new WKTReader();
            Geometry geometry = reader.read(wkt);
            geometry.setSRID(srid);
            return geometry;
        } catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 坐标转换
     *
     * @param y
     * @param x
     * @param dh
     * @return
     * @throws Exception
     */
    public static double[] transTo4490fromProjectionByEpsg(double x, double y, String dh) throws Exception {
        String epsgSource = "";
        switch (dh) {
            //6度分带
            case "13":
                epsgSource = "EPSG:4491";
                break;
            case "14":
                epsgSource = "EPSG:4492";
                break;
            case "15":
                epsgSource = "EPSG:4493";
                break;
            case "16":
                epsgSource = "EPSG:4494";
                break;
            case "17":
                epsgSource = "EPSG:4495";
                break;
            case "18":
                epsgSource = "EPSG:4496";
                break;
            case "19":
                epsgSource = "EPSG:4497";
                break;
            case "20":
                epsgSource = "EPSG:4498";
                break;
            case "21":
                epsgSource = "EPSG:4499";
                break;
            case "22":
                epsgSource = "EPSG:4500";
                break;
            case "23":
                epsgSource = "EPSG:4501";
                break;
            //3度分带
            case "25":
                epsgSource = "EPSG:4513";
                break;
            case "26": //
                epsgSource = "EPSG:4514";
                break;
            case "27": //
                epsgSource = "EPSG:4515";
                break;
            case "28":  //
                epsgSource = "EPSG:4516";
                break;
            case "29":  //
                epsgSource = "EPSG:4517";
                break;
            case "30":  //
                epsgSource = "EPSG:4518";
                break;
            case "31":  //
                epsgSource = "EPSG:4519";
                break;
            case "32":  //
                epsgSource = "EPSG:4520";
                break;
            case "33":  //
                epsgSource = "EPSG:4521";
                break;
            case "34":   //
                epsgSource = "EPSG:4522";
                break;
            case "35":   //
                epsgSource = "EPSG:4523";
                break;
            case "36":  //
                epsgSource = "EPSG:4524";
                break;
            case "37":  //
                epsgSource = "EPSG:4525";
                break;
            case "38":   //'EPSG:':
                epsgSource = "EPSG:4526";
                break;
            case "39"://'EPSG:':
                epsgSource = "EPSG:4527";
                break;
            case "40"://'EPSG:':
                epsgSource = "EPSG:4528";
                break;
            case "41"://'EPSG:':
                epsgSource = "EPSG:4529";
                break;
            case "42"://'EPSG:':
                epsgSource = "EPSG:4530";
                break;
            case "43"://'EPSG:':
                epsgSource = "EPSG:4531";
                break;
            case "44"://'EPSG:':
                epsgSource = "EPSG:4532";
                break;
            case "45"://'EPSG:':
                epsgSource = "EPSG:4533";
                break;
        }
        return transFromByEpsg(x, y, epsgSource, "EPSG:4490");
    }

    /**
     * 坐标投影转换
     *
     * @param x
     * @param y
     * @param epsgSource
     * @param epsgTarget
     * @return
     * @throws Exception
     */
    public static double[] transFromByEpsg(double x, double y, String epsgSource, String epsgTarget) throws Exception {
        Coordinate sourceCoord = new Coordinate(y,x);
        Coordinate targetCoord = new Coordinate(0, 0);
        try {
            CoordinateReferenceSystem crsSource = CRS.decode(epsgSource);
            CoordinateReferenceSystem crsTarget = CRS.decode(epsgTarget);
            MathTransform transform = CRS.findMathTransform(crsSource, crsTarget);
            JTS.transform(sourceCoord, targetCoord, transform);
            double[] targetCoords = {targetCoord.x,targetCoord.y};
            return targetCoords;
        } catch (TransformException te) {
            throw new Exception("坐标系转换错误：TransformException:" + te.getMessage());
        } catch (FactoryException fe) {
            throw new Exception("坐标系转换错误：FactoryException:" + fe.getMessage());
        } catch (Exception e) {
            throw new Exception("坐标系转换错误：Exception:" + e.getMessage());
        }
    }


    /**
     * 创建点坐标
     * @param x 经度
     * @param y 纬度
     * @return
     */
    public static Point createPoint(Double x, Double y){
        //创建几何工厂
        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
        //创建一个几何坐标
        Coordinate coordinate = new Coordinate(x, y);
        return geometryFactory.createPoint(coordinate);
    }

    /**
     * 将要素的坐标系转为相对应的坐标系
     * @param feature 要素类
     * @param targetSrid 坐标系id
     * @return
     */
    public static Geometry coordinateTransform(SimpleFeature feature, int targetSrid){
        if (StringUtils.isNull(feature)){
            return null;
        }
        try {
            CRSAuthorityFactory factory = CRS.getAuthorityFactory(true);
            CoordinateReferenceSystem target = factory.createCoordinateReferenceSystem("EPSG:" + targetSrid);
            CoordinateReferenceSystem coordinateReferenceSystem = feature.getDefaultGeometryProperty().getDescriptor().getCoordinateReferenceSystem();
            if (coordinateReferenceSystem == null){
                Geometry res = (Geometry)feature.getDefaultGeometry();
                res.setSRID(targetSrid);
                return res;
            }
            MathTransform transform = CRS.findMathTransform(coordinateReferenceSystem, target,true);
            Geometry res = JTS.transform((Geometry)feature.getDefaultGeometry(), transform);
            if (res != null){
                res.setSRID(targetSrid);
            }
            return res;
        }catch (FactoryException | TransformException e){
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 面坐标处理解析成WKT格式
     * 第一种方式
     * @param coordinatesStr 一串坐标
     * @return
     *
     * 4348121.92,38610084.30
     * 4348076.60,38611233.20
     * 4347543.64,38611157.40
     * 4347515.09,38611985.26
     * 4346651.97,38612040.25
     * 4346493.69,38611280.02
     * 4346043.13,38610778.17
     * 4345917.48,38609708.95
     * 4346602.51,38609067.42
     */
    public static String CoordinateDisposeWKT1(String coordinatesStr){
        coordinatesStr = coordinatesStr.trim().replaceAll("\\s+","\n");
        //分割文本获取所有的点坐标
        String[] pointCollection = coordinatesStr.split("[\t\n\r]");
        //一个面最少三个点
        if (pointCollection.length < 3) {
            return null;
        }
        //判断当前坐标串用那种方式解析1.十进制度、2.度分秒、3.投影
        Integer analysisType = polygonAnalysis_type(pointCollection[0].trim().split(","));
        //存储创建好的点坐标几何
        Coordinate[] coordinates = new Coordinate[pointCollection.length];
        //循环每个坐标，验真坐标的正确性
        for (int i = 0; i < pointCollection.length; i++) {
            //根据","分割x y
            String[] pointStr = pointCollection[i].trim().split(",");
            if (pointStr.length != 2) {
                return null;
            }
            Point point = polygonAnalysis_point(pointStr, analysisType);
            //其中有一个点存在错误该图形不正确
            if (StringUtils.isNull(point)) {
                return null;
            }
            //创建点几何
            coordinates[i] = point.getCoordinate();
        }
        Polygon polygon = GeometryUtil.createPolygon(coordinates);
        //创建多面类型
        MultiPolygon multiPolygon = GeometryUtil.createMultiPolygon(new Polygon[]{polygon});
        //检查图形的有效性
        if (!multiPolygon.isValid()) {
            return null;
        }
        return multiPolygon.toString();
    }

    /**
     * 面坐标处理解析成WKT格式
     * 第二种方式
     * @param coordinatesStr 一串坐标
     * @return
     *
     * 1,4203487.48,38515918.33, ,
     * 2,4203491.25,38516654.34, ,
     * 3,4203431.04,38516773.13, ,
     * 4,4203336.43,38516829.18, ,
     * 5,4203273.42,38516862.76, ,
     * 6,4203217.14,38516856.54, ,
     * 7,4203189.85,38516751.12, ,
     * 8,4203189.85,38516663.19, ,
     * 9,4203093.83,38516717.14, ,
     * 10,4203050.36,38516838.10, ,
     * 11,4202394.67,38516765.61, ,
     * 12,4202312.69,38516211.71, ,
     * *,632.5,350, ,1
     */
    public static String CoordinateDisposeWKT2(String coordinatesStr){
        String[] coordinatesArry = coordinatesStr.split(",");
        //判断当前坐标串用那种方式解析1.十进制度、2.度分秒、3.投影
        Integer analysisType = polygonAnalysis_type(new String[]{coordinatesArry[1],coordinatesArry[2]});
        //坐标面集合
        Map<List<Coordinate>,Integer> CoordinateList = new LinkedMap<>();
        //坐标点集合
        List<Coordinate> pointList = new ArrayList<>();
        //坐标解析
        for (int i = 3; i < coordinatesArry.length; i+=4) {
            String sign = coordinatesArry[i-3];
            sign = sign.trim();
            //结束符
            if ("*".equals(sign)){
                String[] end = coordinatesArry[i+1].split(" ");
                CoordinateList.put(pointList,Integer.parseInt(end[0]));
                pointList = new ArrayList<>();
                continue;
            }
            String x = coordinatesArry[i-2].trim();
            String y = coordinatesArry[i-1].trim();
            Point point = polygonAnalysis_point(new String[]{x,y}, analysisType);
            pointList.add(point.getCoordinate());
        }
        //坐标转为面
        List<List<Polygon>> multiPolygonList = new ArrayList<>();
        List<Polygon> polygonList = new ArrayList<>();
        for (List<Coordinate> k : CoordinateList.keySet()) {
            //获取结束值
            Integer v = CoordinateList.get(k);
            Coordinate[] coordinates = new Coordinate[k.size()];
            Polygon polygon = GeometryUtil.createPolygon(k.toArray(coordinates));
            if (v == 1){
                multiPolygonList.add(polygonList);
                polygonList = new ArrayList<>();
            }
            polygonList.add(polygon);
        }
        multiPolygonList.remove(0);
        multiPolygonList.add(polygonList);
        //处理多面或面带洞
        polygonList = new ArrayList<>();
        for (List<Polygon> list : multiPolygonList) {
            if (list.size() <= 1){
                polygonList.addAll(list);
                continue;
            }
            LinearRing[] linearRings = new LinearRing[list.size()-1];
            for (int i = 1; i < list.size(); i++) {
                linearRings[i-1] = list.get(i).getExteriorRing();
            }
            Polygon polygonWithHoles = GeometryUtil.createPolygonWithHoles(list.get(0).getExteriorRing(), linearRings);
            polygonList.add(polygonWithHoles);
        }
        //创建多面
        Polygon[] polygons = new Polygon[polygonList.size()];
        MultiPolygon multiPolygon = GeometryUtil.createMultiPolygon(polygonList.toArray(polygons));
        return multiPolygon.toString();
    }

    /**
     * 面坐标处理解析成WKT格式
     * 第三种方式
     * @param coordinatesStr 一串坐标
     * @return
     *
     * 2,5,1,4421028.05,39571109.36,2,4421062.05,39571064.36,3,4421110.05,39571178.36,4,4421088.05,39571236.36,5,4421024.05,39571217.36,103,47,,1,3,7,4420967.05,39571412.36,8,4420819.05,39571421.36,6,4420876.05,39571372.36,103,47,,1,
     */
    public static String CoordinateDisposeWKT3(String coordinatesStr){
        String[] coordinatesArry = coordinatesStr.split(",");
        //判断当前坐标串用那种方式解析1.十进制度、2.度分秒、3.投影
        Integer analysisType = polygonAnalysis_type(new String[]{coordinatesArry[3],coordinatesArry[4]});
        //面的个数
        Integer polygonNum = Integer.parseInt(coordinatesArry[0]);
        //第一个面的点个数
        Integer pointNum = Integer.parseInt(coordinatesArry[1]);
        //第一个X点
        Integer x = 3;
        //第一个Y点
        Integer y = 4;
        //存放多个面
        List<Polygon> multiPolygonList = new ArrayList<>();
        //存放为洞的面
        List<Polygon> holePolygon = new ArrayList<>();
        for (int i = 0; i < polygonNum; i++) {
            Coordinate[] coordinates = new Coordinate[pointNum];
            for (int j = 0; j < pointNum; j++,x+=3,y+=3) {
                //x点
                String lon = coordinatesArry[x];
                //y点
                String lat = coordinatesArry[y];
                //转为点
                Point point = polygonAnalysis_point(new String[]{lon,lat}, analysisType);
                coordinates[j] = point.getCoordinate();
            }
            //创建面
            Polygon polygon = GeometryUtil.createPolygon(coordinates);
            //判断是多面或带洞的面
            Integer type = Integer.parseInt(coordinatesArry[y+1]);
            if (type == -1){
                holePolygon.add(polygon);
            }else {
                multiPolygonList.add(polygon);
            }
            if (i < polygonNum-1){
                //第二个或更多面的点数
                pointNum = Integer.parseInt(coordinatesArry[y+2]);
                x+=5;
                y+=5;
            }
        }

        MultiPolygon multiPolygon = GeometryUtil.createMultiPolygon(multiPolygonList.toArray(new Polygon[multiPolygonList.size()]));
        //存在带洞的情况
        if (holePolygon.size() != 0){
            List<LinearRing> linearRingList = holePolygon.stream().map(hole -> hole.getExteriorRing()).collect(Collectors.toList());
            //创建带洞的面
            Coordinate[] coordinates = multiPolygon.getCoordinates();
            GeometryFactory geometryFactory = new GeometryFactory();
            LinearRing ring = geometryFactory.createLinearRing(coordinates);
            Polygon polygonWithHoles = GeometryUtil.createPolygonWithHoles(ring, linearRingList.toArray(new LinearRing[holePolygon.size()]));
            multiPolygon = GeometryUtil.createMultiPolygon(new Polygon[]{polygonWithHoles});
        }
        //检查图形的有效性
        if (!multiPolygon.isValid()) {
            return null;
        }
        return multiPolygon.toString();
    }

    /**
     * 面坐标处理解析成WKT格式
     * 第四种方式
     * @param coordinatesStr 一串坐标
     * @return
     *
     * 2,4,114.0643000,41.0300000,114.0820000,41.0300000,114.0820000,41.0200000,114.0643000,41.0200000,0,0,0,4,114.0721000,41.0219000,114.0725000,41.0214000,114.0707000,41.0203000,114.0703000,41.0207000,-1,0,0,
     */
    public static String CoordinateDisposeWKT4(String coordinatesStr){
        String[] coordinatesArry = coordinatesStr.split(",");
        //判断当前坐标串用那种方式解析1.十进制度、2.度分秒、3.投影
        Integer analysisType = polygonAnalysis_type(new String[]{coordinatesArry[2],coordinatesArry[3]});
        //面的个数
        Integer polygonNum = Integer.parseInt(coordinatesArry[0]);
        //第一个面的点个数
        Integer pointNum = Integer.parseInt(coordinatesArry[1]);
        //第一个X点
        Integer x = 2;
        //第一个Y点
        Integer y = 3;
        //存放多个面
        List<Polygon> multiPolygonList = new ArrayList<>();
        //存放为洞的面
        List<Polygon> holePolygon = new ArrayList<>();
        for (int i = 0; i < polygonNum; i++) {
            Coordinate[] coordinates = new Coordinate[pointNum];
            for (int j = 0; j < pointNum; j++,x+=2,y+=2) {
                //x点
                String lon = coordinatesArry[x];
                //y点
                String lat = coordinatesArry[y];
                //转为点
                Point point = polygonAnalysis_point(new String[]{lon,lat}, analysisType);
                coordinates[j] = point.getCoordinate();
            }
            //创建面
            Polygon polygon = GeometryUtil.createPolygon(coordinates);
            //判断是多面或带洞的面
            Integer type = Integer.parseInt(coordinatesArry[x]);
            if (type == -1){
                holePolygon.add(polygon);
            }else {
                multiPolygonList.add(polygon);
            }
            if (i < polygonNum-1){
                //第二个或更多面的点数
                pointNum = Integer.parseInt(coordinatesArry[y+2]);
                x+=4;
                y+=4;
            }
        }

        MultiPolygon multiPolygon = GeometryUtil.createMultiPolygon(multiPolygonList.toArray(new Polygon[multiPolygonList.size()]));
        //存在带洞的情况
        if (holePolygon.size() != 0){
            List<LinearRing> linearRingList = holePolygon.stream().map(hole -> hole.getExteriorRing()).collect(Collectors.toList());
            //创建带洞的面
            Coordinate[] coordinates = multiPolygon.getCoordinates();
            GeometryFactory geometryFactory = new GeometryFactory();
            LinearRing ring = geometryFactory.createLinearRing(coordinates);
            Polygon polygonWithHoles = GeometryUtil.createPolygonWithHoles(ring, linearRingList.toArray(new LinearRing[holePolygon.size()]));
            multiPolygon = GeometryUtil.createMultiPolygon(new Polygon[]{polygonWithHoles});
        }
        //检查图形的有效性
        if (!multiPolygon.isValid()) {
            return null;
        }
        return multiPolygon.toString();
    }

    /**
     * 根据解析类型创建点 (面解析方法中使用)
     *
     * @param pointStr     坐标点x y数组
     * @param analysisType 解析类型 1.十进制度、2.度分秒、3.投影
     * @return
     */
    public static Point polygonAnalysis_point(String[] pointStr, Integer analysisType) {
        //根据得到的类型解析每个点
        switch (analysisType) {
            case 1:
                return pointDecimalism(pointStr[0], pointStr[1]);
            case 2:
                return pointDFM(pointStr[0], pointStr[1]);
            case 3:
                return pointEPSG4490(pointStr[0], pointStr[1]);
        }
        return null;
    }

    /**
     * 获取坐标解析类型 1.十进制度、2.度分秒、3.投影 0.错误类型
     *
     * @param pointIndex1 坐标x y数组
     * @return
     */
    public static Integer polygonAnalysis_type(String[] pointIndex1) {
        if (pointIndex1.length != 2) {
            return 0;
        }
        Point pointDecimalism = pointDecimalism(pointIndex1[0], pointIndex1[1]);
        Point pointDFM = pointDFM(pointIndex1[0], pointIndex1[1]);
        Point pointEPSG4490 = pointEPSG4490(pointIndex1[0], pointIndex1[1]);
        if (StringUtils.isNotNull(pointDecimalism)) {
            return 1;
        }
        if (StringUtils.isNotNull(pointDFM)) {
            return 2;
        }
        if (StringUtils.isNotNull(pointEPSG4490)) {
            return 3;
        }
        return 0;
    }

    /**
     * 检查输入的十进制度点坐标
     *
     * @param x 经度
     * @param y 纬度
     */
    public static Point pointDecimalism(String x, String y) {
        if (!(BasicUtil.isDouble(x, CoordinateUtil.LNG_PATTERN) && BasicUtil.isDouble(y, CoordinateUtil.LAT_PATTERN))) {
            return null;
        }
        return CoordinateUtil.createPoint(Double.parseDouble(x), Double.parseDouble(y));
    }

    /**
     * 检查输入的度分秒点坐标
     *
     * @param x 经度
     * @param y 纬度
     */
    public static Point pointDFM(String x, String y) {
        if (!(BasicUtil.isPattern(x, CoordinateUtil.LNG_PATTERN_D) && BasicUtil.isPattern(y, CoordinateUtil.LAT_PATTERN_D))){
            return null;
        }
        //转为十进制度
        double lon = Double.parseDouble(CoordinateUtil.Dms2D(x));
        double lat = Double.parseDouble(CoordinateUtil.Dms2D(y));
        return CoordinateUtil.createPoint(lon, lat);
    }

    /**
     * 检查输入的2000大地点坐标
     *
     * @param x 经度
     * @param y 纬度
     */
    public static Point pointEPSG4490(String x, String y) {
        try {
            double[] doubles = CoordinateUtil
                    .transTo4490fromProjectionByEpsg(Double.parseDouble(x), Double.parseDouble(y), y.substring(0, 2));
            return CoordinateUtil.createPoint(doubles[0], doubles[1]);
        } catch (Exception e) {
            return null;
        }
    }


    /**
     * 读取WKT格式数据
     * @param WKT
     * @return
     */
    public static Geometry readWKT(String WKT){
        //读取坐标
        WKTReader2 wktReader = new WKTReader2();
        try {
            return wktReader.read(WKT);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}
